import Config from '../Config'
import { EKeyCode, EEventType } from './Enum'
import Enemy from './Enemy'
import Plane from './Plane'
import Bullet from './Bullet'
import EventManager from '../EventManager'

export default class gameControl extends Laya.Script {
    /** @prop {name:enemy1, tips:"敌机1预制体", type:Prefab}*/
    public enemy1: Laya.Prefab;
    /** @prop {name:enemy2, tips:"敌机2预制体", type:Prefab}*/
    public enemy2: Laya.Prefab;
    /** @prop {name:enemy3, tips:"敌机3预制体", type:Prefab}*/
    public enemy3: Laya.Prefab;
    /** @prop {name:plane, tips:"飞机预制体", type:Prefab}*/
    public plane: Laya.Prefab;
    /** @prop {name:bullet, tips:"子弹预制体", type:Prefab}*/
    public bullet: Laya.Prefab;
    /** @prop {name:buff, tips:"buff预制体", type:Prefab}*/
    public buff: Laya.Prefab;

    /**开始时间 */
    private _startTime: number = 0;
    /**子弹和敌人所在的容器 */
    private _mainBox: Laya.Box;
    /**飞机 */
    private _plane: Laya.Sprite;
    /**移动方向 */
    private _moveStatus: EKeyCode[] = [];
    /**初始敌人出现间隔 */
    private _enemyAppearCD: number;
    /**难度系数 */
    private _hardDegree: number;
    /**上次射击时间 */
    private _lastShotTime: number
    /**上次出现敌人时间 */
    private _lastEnemyTime: number;
    /**上次刷新难度时间 */
    private _lastHardTime: number


    constructor() { super(); }

    onEnable(): void {
        this._mainBox = this.owner.getChildByName('mainBox') as Laya.Box;
        this.addEvent()
        this.startGame()
        this.createPlane()
    }

    addEvent(): void {
        EventManager.Ins.addListener(EEventType.CreateBuff, this, this.createBuff);
    }

    startGame() {
        this._startTime = this._lastShotTime =
        this._lastEnemyTime = this._lastHardTime = Date.now();
        this._enemyAppearCD = 800;
        this._hardDegree = 2.4;
    }

    onUpdate(): void {
        let time = Date.now();

        if (time > this._lastHardTime + Config.addHardInterval) {
            this._lastHardTime = time;
            this.setHard()
        }

        if (time > this._lastShotTime + Config.bulletCD) {
            this._lastShotTime = time;
            this.createBullet();

        }

        if (time > this._lastEnemyTime + this._enemyAppearCD) {
            this._lastEnemyTime = time;
            this.createEnemy()
        }

        this.checkMove()
    }

    /**设置难度 */
    setHard(): void {
        let time = Date.now();
        this._hardDegree = Config.initHardDegree + (time - this._startTime) / Config.addHardInterval * 0.1
        this._enemyAppearCD -= 20
    }

    createEnemy(): void {
        let level: number = Math.min(3, Math.ceil(Math.random() * this._hardDegree))
        let levelStr: string = 'enemy' + level
        let enemy: Laya.Sprite = Laya.Pool.getItemByCreateFun(levelStr, this[levelStr].create, this[levelStr])
        enemy.pos(Math.random() * (Laya.stage.width - 100), -100);
        let enemyComponent = enemy.getComponent(Enemy);
        enemyComponent.hp = level * 2;
        enemyComponent.level = level;
        this._mainBox.addChild(enemy);
    }

    createBullet(): void {
        const planeLv: number = this._plane.getComponent(Plane).level;
        const bulletNum: number = 1 + (planeLv - 1) * 2 //1,3,5,7...;
        const yVel: number = Config.bulletYVel;
        const initAngle: number = 0 - (planeLv - 1) * 0.3;
        for (let i: number = 0, len = bulletNum; i <= len - 1; i++) {
            const bullet: Laya.Sprite = Laya.Pool.getItemByCreateFun('bullet', this.bullet.create, this.bullet)
            const bulletComp = bullet.getComponent(Bullet);
            const xVel = Math.tan(initAngle + 0.3 * i) * yVel
            bullet.pos(this._plane.x + 0.5 * this._plane.width, this._plane.y);
            bulletComp.setVelocity(xVel, yVel)
            this._mainBox.addChild(bullet);
        }
    }

    createPlane(): void {
        this._plane = Laya.Pool.getItemByCreateFun('plane', this.plane.create, this.plane)
        this._plane.pos(300, 1000);
        this._mainBox.addChild(this._plane);
    }

    createBuff(x,y): void {
        let buff = Laya.Pool.getItemByCreateFun('buff', this.buff.create, this.buff)
        buff.pos(x, y);
        this._mainBox.addChild(buff);
    }

    onKeyDown(e: laya.events.Event): void {
        this.dealKeyEvent(e.keyCode, true)
    }

    onKeyUp(e: laya.events.Event): void {
        this.dealKeyEvent(e.keyCode, false)
    }

    dealKeyEvent(keyCode, isKeyDown): void {
        switch (keyCode) {
            case EKeyCode.W:
            case EKeyCode.A:
            case EKeyCode.S:
            case EKeyCode.D:
                if (isKeyDown && this._moveStatus.indexOf(keyCode) === -1) {
                    this._moveStatus.push(keyCode)
                }
                if (!isKeyDown) {
                    for (let i: number = 0, len = this._moveStatus.length; i <= len - 1; i++) {
                        if (this._moveStatus[i] === keyCode) {
                            this._moveStatus.splice(i, 1)
                            break;
                        }
                    }
                }
                break;
        }
    }

    checkMove(): void {
        if (this._moveStatus.length !== 0) {
            let speed: number = Config.planeMoveFactor * Laya.timer.delta;
            let nextX = this._plane.x;
            let nextY = this._plane.y;
            this._moveStatus.forEach(item => {
                switch (item) {
                    case EKeyCode.W:
                        nextY -= speed;
                        break
                    case EKeyCode.A:
                        nextX -= speed;
                        break;
                    case EKeyCode.S:
                        nextY += speed;
                        break;
                    case EKeyCode.D:
                        nextX += speed;
                        break;
                }
            })
            nextX = Math.min(Laya.stage.width - this._plane.width, nextX)
            nextX = Math.max(0, nextX)
            nextY = Math.min(Laya.stage.height - this._plane.height, nextY)
            nextY = Math.max(0, nextY)
            this._plane.pos(nextX, nextY)
        }
    }


    onDisable(): void {

    }
}